#ifndef _BACKTRACKLEXER_H_
#define _BACKTRACKLEXER_H_

#include <string>

using namespace std;

#include "token.h"
#include "lexer.h"
#include "common.h"

class BacktrackLexer : public Lexer {
public:
    string get_token_name(int x) {
        return token_names[x];
    }

    BacktrackLexer(string input): Lexer(input) { }
private:
    bool is_letter() {
        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
    }
public:
    Token *next_token() {
        while (c != EOFF) {
            switch (c) {
                case ' ':
                case '\t':
                case '\n':
                case '\r':
                    WS();
                    continue;
                case ',':
                    consume();
                    return new Token(COMMA, ",");
                case '[':
                    consume();
                    return new Token(LBRACK, "[");
                case ']':
                    consume();
                    return new Token(RBRACK, "]");
                case '=':
                    consume();
                    return new Token(EQUALS, "=");
                default:
                    if (is_letter())
                        return name();
                    string s = "invalid character: ";
                    s.push_back(c);
                    throw Error(s);
            }
        }
        return new Token(EOF_TYPE, "<EOF>");
    }
private:
    Token *name() {
        string s;
        while (is_letter()) {
            s.push_back(c);
            LETTER();
        }
        return new Token(NAME, s);
    }

    void LETTER() {
        if (is_letter())
            consume();
        else {
            string s = "expecting LETTER; found ";
            s.push_back(c);
            throw Error(s);
        }
    }

    void WS() {
        while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
            advance();
    }
};

#endif
